package com.ilovepostcard.view;

import com.ilovepostcard.R;
import com.ilovepostcard.utils.Constants;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class EditPostcardView extends View {

	private static final String TAG = "postcard";
	private static final int NONE = 0; 
    private static final int DRAG = 1; 
    private static final int ZOOM = 2; 
    
    public final static int EXPECTWIDTH = 898;
    public final static int EXPECTHEIGHT = 614;
    int mode = NONE; 
    boolean matrixCheck = false; 
	private int mDefaultWidth;
	private int mDefaultHeight;
	private int mClipWidth;
	private int mClipHeight;
	private int mWidth;
	private int mHeight;
	private Bitmap mSrcBitmap;
	private int mSrcBitmapWidth;
	private int mSrcBitmapHeight;
	private int mTop;
	private int mLeft;
	private int mLastX;
	private int mLastY;
	private float mScale;
	private final Paint mOutlinePaint = new Paint();
	private RectF focusRect;
	private Path path = new Path();
	private int mMarginLeft = 50;
	private int mMarginTop = 50;
	

	private Bitmap mOrignalBitmap;

	private int rotateAngle;

	// drawing related
	private Rect mDrawSrcRect;
	private Rect mDrawDestRect;
	
	private String mFilePath;
	Matrix matrix;
	Matrix matrix1 = new Matrix(); 
    Matrix savedMatrix = new Matrix(); 

    PointF start = new PointF(); 
    PointF mid = new PointF(); 
    float oldDist = 1f; 
    float oldRotation = 0;
    private boolean showTip;
    private Bitmap tip;
    
    public class ImageState {  
    	  public float left;  
    	  public float top;  
    	  public float right;  
    	  public float bottom;  
    	} 
    
    
	public EditPostcardView(Context context) {
		super(context);
		
		init(context);
	}

	public EditPostcardView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	public EditPostcardView(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.EditPostcardView);
        
        mDefaultWidth = a.getInt(R.styleable.EditPostcardView_widgetWidth, 364);
        mDefaultHeight = a.getInt(R.styleable.EditPostcardView_widgetHeight, 256);
        mClipWidth = a.getInt(R.styleable.EditPostcardView_clipWidth, 300);
        mClipHeight = a.getInt(R.styleable.EditPostcardView_clipHeight, 200);
        
        mMarginLeft = a.getInt(R.styleable.EditPostcardView_marginLeft, 50);
        mMarginTop = a.getInt(R.styleable.EditPostcardView_marginTop,50);
        
        Log.d(TAG,"mDefaultWidth="+mDefaultWidth+",mDefaultHeight="+mDefaultHeight);
        a.recycle();
        
		mOutlinePaint.setStrokeWidth(mMarginTop);
		mOutlinePaint.setStyle(Paint.Style.STROKE);
		mOutlinePaint.setAntiAlias(true);
		mOutlinePaint.setColor(0X5fFFFFFF);
		focusRect = new RectF(0, 0, mDefaultWidth, mDefaultHeight);

		path.addRect(focusRect, Path.Direction.CW);

		mScale = 1.0F;
		mDrawSrcRect = new Rect();
		mDrawDestRect = new Rect();
		init(context);
	}

	public void setOrignalBitmap(Bitmap bitmap) {
		mOrignalBitmap = bitmap;
		setDrawBitmap(bitmap);
	}

	public int getOrgWidth()
	{
		if(mOrignalBitmap!= null)
			return mOrignalBitmap.getWidth();
		return 0;
	}
	
	public int getOrgHeight()
	{
		if(mOrignalBitmap!= null)
			return mOrignalBitmap.getHeight();
		
		return 0;
	}
	private void init(Context context)
	{
		matrix = new Matrix(); 
		tip = BitmapFactory.decodeResource(context.getResources(), R.drawable.cpage_edit_picture_notice);
		showTip = true;
	}
	public void setDrawBitmap(Bitmap bitmap) {
		mSrcBitmap = bitmap;

		mSrcBitmapWidth = bitmap.getWidth();
		mSrcBitmapHeight = bitmap.getHeight();

		mWidth = mDefaultWidth;
		mHeight = mDefaultHeight;

		Log.d("postcard",
				"srcw=" + bitmap.getWidth() + "srch=" + bitmap.getHeight());
		ensureCenter();
		invalidate();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(mDefaultWidth, mDefaultHeight);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (mSrcBitmap == null)
			return;

		canvas.save(); 
        canvas.drawBitmap(mSrcBitmap, matrix, null); 
        if(showTip)
        	canvas.drawBitmap(tip, (mDefaultWidth-tip.getWidth())/2, (mDefaultHeight-tip.getHeight())/2, null);
		canvas.drawPath(path, mOutlinePaint);
		
		
		canvas.restore();

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// Log.d("Postcard","x="+event.getX()+",y="+event.getY());

		/*switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// Log.d("Postcard","down x="+event.getX()+",y="+event.getY());
			mLastX = (int) event.getX();
			mLastY = (int) event.getY();
			break;
		case MotionEvent.ACTION_MOVE:
			// Log.d("Postcard","move x="+event.getX()+",y="+event.getY());

			handleMotion((int) (event.getX() - mLastX),
					(int) (event.getY() - mLastY));
			{
				mLastX = (int) event.getX();
				mLastY = (int) event.getY();
			}
			break;
		case MotionEvent.ACTION_POINTER_UP:
			// Log.d("Postcard","up x="+event.getX()+",y="+event.getY());
			break;
		}

		return true;*/
		switch (event.getAction() & MotionEvent.ACTION_MASK) { 
        case MotionEvent.ACTION_DOWN: 
            mode = DRAG; 
            mLastX = (int)event.getX(); 
            mLastY = (int)event.getY(); 
            savedMatrix.set(matrix); 
            
            if(showTip)
            {
            	 showTip = false;
                 invalidate(); 
            }
           
            break; 
        case MotionEvent.ACTION_POINTER_DOWN: 
            mode = ZOOM; 
            oldDist = spacing(event); 
            oldRotation = rotation(event); 
            savedMatrix.set(matrix); 
            midPoint(mid, event); 
            break; 
        case MotionEvent.ACTION_MOVE: 
            if (mode == ZOOM) { 
            	handleMotion((int) (event.getX() - mLastX),
    					(int) (event.getY() - mLastY));
    			
                matrix1.set(savedMatrix); 
                float newDist = spacing(event); 
                float scale = newDist / oldDist; 
                matrix1.postScale(scale, scale, mid.x, mid.y);
                matrixCheck = matrixCheck(); 
                if (matrixCheck == false) { 
                    matrix.set(matrix1); 
                    invalidate(); 
                } 
            } else if (mode == DRAG) { 
                matrix1.set(savedMatrix); 
                matrix1.postTranslate(event.getX() - mLastX, event.getY() 
                        - mLastY);
                matrixCheck = matrixCheck(); 
                matrixCheck = matrixCheck(); 
                if (matrixCheck == false) { 
                    matrix.set(matrix1); 
                    invalidate(); 
                } 
            } 
            break; 
        case MotionEvent.ACTION_UP: 
        case MotionEvent.ACTION_POINTER_UP: 
            mode = NONE; 
            savedMatrix.set(matrix); 
            break; 
        } 
		
		super.onTouchEvent(event);
		return true;
	}

	private void handleMotion(int dx, int dy) {
		// Log.d(TAG, "dx=" + dx + "  dy=" + dy);

		mTop -= dy;
		mLeft -= dx;

		//Log.d(TAG, "mTop=" + mTop + ",mLeft=" + mLeft);

		if (mTop < -mMarginTop)
			mTop = -mMarginTop;
		
		if (mLeft < -mMarginLeft)
			mLeft = -mMarginLeft;

		//Log.d(TAG, "mTop=" + mTop + ",mLeft=" + mLeft);

		int maxY = mSrcBitmapHeight - mMarginTop - 8 - mClipHeight;
		int maxX = mSrcBitmapWidth - mMarginLeft - 8 - mClipWidth;
		
		if (mTop > maxY)
			mTop = maxY;
		if (mLeft > maxX)
			mLeft = maxX;

		//Log.d(TAG, "mTop=" + mTop + ",mLeft=" + mLeft);
		
		//invalidate();
	}

	
	public void makeSmaller() {
		float newScale = (float) (mScale - 0.1);
		
		int width = mOrignalBitmap.getWidth();
		int height = mOrignalBitmap.getHeight();
		
		if(getRotationAngle() % 180 != 0){
			width = mOrignalBitmap.getHeight();
			height = mOrignalBitmap.getWidth();
		}
		
		int destWidth = (int) ( width * newScale);
		int destHeight = (int) ( height * newScale);
		Log.d(TAG,"scale with="+destWidth+",scale height="+destHeight);
	

		if (destWidth < mClipWidth || destHeight < mClipHeight){
			Log.d(TAG,"return here");
			return;
		}

		Matrix matrix = new Matrix();
		if (rotateAngle != 0)
			matrix.setRotate(rotateAngle);

		matrix.postScale(newScale, newScale);

		Bitmap resizedBitmap = Bitmap.createBitmap(mOrignalBitmap, 0, 0,
				mOrignalBitmap.getWidth(), mOrignalBitmap.getHeight(), matrix,
				false);
		mScale = newScale;
		setDrawBitmap(resizedBitmap);
	}

	public void makeBigger() {
		float newScale = (float) (mScale + 0.1);
		if (newScale > 1.6)
			return;

		Matrix matrix = new Matrix();
		if (rotateAngle != 0)
			matrix.setRotate(rotateAngle);
		matrix.postScale(newScale, newScale);

		Bitmap resizedBitmap = Bitmap.createBitmap(mOrignalBitmap, 0, 0,
				mOrignalBitmap.getWidth(), mOrignalBitmap.getHeight(), matrix,
				false);
		mScale = newScale;
		setDrawBitmap(resizedBitmap);
	}

	public void rotate(boolean is_clockwise) {
		Matrix matrix = new Matrix();

		if (is_clockwise) {
			rotateAngle -= 90;
		} else {
			rotateAngle += 90;
		}

		matrix.setRotate(rotateAngle);
		matrix.postScale(mScale, mScale);
		Bitmap bitmap = Bitmap.createBitmap(mOrignalBitmap, 0, 0,
				mOrignalBitmap.getWidth(), mOrignalBitmap.getHeight(), matrix,
				true);

		//make sure the image is big enough for showing
		while(bitmap.getWidth() < mClipWidth || bitmap.getHeight() < mClipHeight){
			mScale+=0.1;
			matrix.reset();
			matrix.setRotate(rotateAngle);
			matrix.postScale(mScale, mScale);
			bitmap.recycle();
			bitmap = Bitmap.createBitmap(mOrignalBitmap, 0, 0,
					mOrignalBitmap.getWidth(), mOrignalBitmap.getHeight(), matrix,
					true);
			if(bitmap.getWidth() > mClipWidth && bitmap.getHeight() > mClipHeight)
				break;
		}

		setDrawBitmap(bitmap);
	}
	
	
	public Bitmap getScaledBitmapEx()
	{
		Bitmap bitmap = null;
		Rect srcRect = null;
		Rect destRect = null;
		float[] values = new float[9];   
		matrix.getValues(values);   
		if(values[0]== 1.0)
		{
			return getNoScaleBitmap();
		}
		else
		{
			return this.getScaleBitmapEx2();
		}
		/*ImageState mapState = new ImageState();   
		mapState.left = values[2] > mMarginLeft ? 0 :values[2];   
		mapState.top = values[5] > mMarginTop ? 0 : values[5]; 
		
		Bitmap scaleBitmap= Bitmap.createBitmap(mSrcBitmap, 0, 0, mSrcBitmap.getWidth(), mSrcBitmap.getHeight(), matrix, true);
		mapState.right = (scaleBitmap.getWidth()+ mapState.left) >0 ? (scaleBitmap.getWidth()+ mapState.left):(mSrcBitmap.getWidth()+ mapState.left);
		mapState.bottom = (scaleBitmap.getHeight()+mapState.top) >0 ? (scaleBitmap.getHeight()+mapState.top):(mSrcBitmap.getHeight()+mapState.top);
		
		
		int cutX,cutY;
		cutX = (int)(mapState.left*-1)+ mMarginLeft;
		cutY = mMarginTop+(int)(mapState.top*-1);
		int clipw = (int)(mapState.right-mapState.left),cliph = (int)(mapState.bottom-mapState.top);
		if((mapState.right-mapState.left) > EXPECTWIDTH)
			clipw = EXPECTWIDTH;
		
		if((mapState.bottom-mapState.top) > EXPECTHEIGHT)
			cliph = EXPECTHEIGHT;
		

		if((mapState.right-mapState.left) < (EXPECTWIDTH*values[0]) && (mapState.bottom-mapState.top) < (EXPECTHEIGHT*values[0]))
		{
			cutX =0;
			cutY = 0;
		}
		cliph = (int)(cliph*values[0]);
		clipw = (int)(clipw*values[0]);
		int bottom = (cliph+cutY)> (int) (mapState.bottom+cutY) ? (int) (mapState.bottom+cutY) : (cliph+cutY);
		int right = (clipw+cutX) > (int)(mapState.right+cutX)? (int) (mapState.right+cutX) : (clipw+cutX);
		srcRect = new Rect(cutX,cutY,right,bottom);
		
		destRect = new Rect(0,0,srcRect.width(),srcRect.height());
		
		bitmap = Bitmap.createBitmap(srcRect.width(),srcRect.height(), Config.ARGB_8888);
		Log.d(Constants.TAG,"srcRect="+srcRect);
		
		
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(scaleBitmap, srcRect, destRect, null);
		canvas.save();
		
		Log.d("EditImage", "scaleBitmap w:"+scaleBitmap.getWidth()+",h:"+scaleBitmap.getHeight()+",srcx:"+srcRect.left+",srcy:"+srcRect.top+",srcbottom:"+srcRect.bottom+",srcRight:"+srcRect.right);
		return bitmap;
*/	}
	
	public Bitmap getScaledBitmapEx1()
	{
		Bitmap bitmap = null;
		Rect srcRect = null;
		Rect destRect = null;
		float[] values = new float[9];   
		matrix.getValues(values);  
		srcRect = new Rect(mLeft+mMarginLeft,mTop+mMarginTop,mLeft+mMarginLeft+mClipWidth,mTop+mMarginTop+mClipHeight);
		bitmap = Bitmap.createBitmap(mClipWidth, mClipHeight, Config.ARGB_8888);
		destRect = new Rect(0,0,mClipWidth,mClipHeight);

		
		Log.d(Constants.TAG,"srcRect="+srcRect);
		
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(mSrcBitmap, srcRect, destRect, null);
		return bitmap;
	}
	
	public Bitmap getScaleBitmapEx2()
	{
		Bitmap bitmap = null;
		Rect srcRect = null;
		Rect destRect = null;
		float fact;
		float[] values = new float[9];   
		matrix.getValues(values);  
		
		fact = values[0];
		ImageState mapState = new ImageState();   
		mapState.left = values[2];
		mapState.top = values[5];
		mapState.right = (mSrcBitmap.getWidth()*fact+ mapState.left);
		mapState.bottom = (mSrcBitmap.getHeight()*fact+mapState.top);
		
		
		int x,y,w,h;
		if(mapState.left>0)
			x = 0;
		else
			x = (int)(-1*mapState.left/fact)+mMarginLeft;
		
		if(mapState.top > 0)
			y = 0;
		else
			y = (int)(-1*mapState.top/fact)+mMarginLeft;
		
		
		int clipw = mClipWidth;
		int clipH = mClipHeight;
		
		if(mapState.left>0)
			clipw = clipw - (int)mapState.left;
		
		if(mapState.top >0)
			clipH = clipH - (int)mapState.top;
		
		int offsetLeft = (int)mapState.left >0 ? (int)(mClipWidth - mapState.left): mClipWidth;
		int offsetTop = (int)mapState.top >0 ? (int)(mClipHeight - mapState.top): mClipHeight;
		w = (int)(offsetLeft/fact);
		h = (int)(offsetTop/fact);
		
		if((mSrcBitmap.getWidth() - x)<w)
			w = mSrcBitmap.getWidth() - x;
		
		if((mSrcBitmap.getHeight() - y)<w)
			h = mSrcBitmap.getHeight() - y;
		
		
		
		
		srcRect = new Rect(x,y,w+x,h+y);
		Log.d(Constants.TAG,"x="+x+",y="+y+",right="+(w+x)+",bottom:"+(h+y));
		destRect = new Rect(0,0,srcRect.width(),srcRect.height());
		
		bitmap = Bitmap.createBitmap(srcRect.width(),srcRect.height(), Config.ARGB_8888);
		
		
		
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(mSrcBitmap, srcRect, destRect, null);
		canvas.save();
		
		Log.d("EditImage", "scaleBitmap w:"+mSrcBitmap.getWidth()+",h:"+mSrcBitmap.getHeight()+",srcx:"+srcRect.left+",srcy:"+srcRect.top+",srcbottom:"+srcRect.bottom+",srcRight:"+srcRect.right);
		return bitmap;

	}
	
	public Bitmap getNoScaleBitmap()
	{
		Bitmap bitmap = null;
		Rect srcRect = null;
		Rect destRect = null;
		float[] values = new float[9];   
		matrix.getValues(values);   
		ImageState mapState = new ImageState();   
		mapState.left =values[2];   
		mapState.top = values[5]; 
		mapState.right = mapState.left + mSrcBitmap.getWidth() * values[0];   
		mapState.bottom = mapState.top + mSrcBitmap.getHeight() * values[0]; 
		
		
		int cutX,cutY;
		cutX = (int)(mapState.left*-1);
		cutY =(int)(mapState.top*-1);
		/*int clipw = (int)(mapState.right-mapState.left),cliph = (int)(mapState.bottom-mapState.top);
		if((mapState.right-mapState.left) > EXPECTWIDTH)
			clipw = EXPECTWIDTH;
		
		if((mapState.bottom-mapState.top) > EXPECTHEIGHT)
			cliph = EXPECTHEIGHT;
		

		if((mapState.right-mapState.left) < EXPECTWIDTH && (mapState.bottom-mapState.top) < EXPECTHEIGHT)
		{
			cutX =0;
			cutY = 0;
		}
		*/
		srcRect = new Rect(cutX,cutY,mClipWidth+cutX,mClipHeight+cutY);
		
		destRect = new Rect(0,0,mClipWidth,mClipHeight);
		
		bitmap = Bitmap.createBitmap(srcRect.width(),srcRect.height(), Config.ARGB_8888);
		Log.d(Constants.TAG,"srcRect="+srcRect);
		Bitmap scaleBitmap= mSrcBitmap;
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(scaleBitmap, srcRect, destRect, null);
		canvas.save();

		return bitmap;
	}
	
	
	protected void center(boolean horizontal, boolean vertical) {

		 Matrix m = new Matrix();
		 m.set(matrix);
		 RectF rect = new RectF(0, 0, mSrcBitmap.getWidth(), mSrcBitmap.getHeight());
		 m.mapRect(rect);

		float height = rect.height();
		float width = rect.width();

		float deltaX = 0, deltaY = 0;

		if (vertical) {
		int screenHeight = mDefaultHeight;
		if (height < screenHeight) {
			deltaY = (screenHeight - height) / 2 - rect.top;
		 } else if (rect.top > 0) {
			 deltaY = -rect.top;
		 } else if (rect.bottom < screenHeight) {
			 deltaY = mDefaultHeight - rect.bottom;
		 }
		 }

		if (horizontal) {
		int screenWidth = mDefaultWidth;
		if (width < screenWidth) {
		 deltaX = (screenWidth - width) / 2 - rect.left;
		 } else if (rect.left > 0) {
		 deltaX = -rect.left;
		 } else if (rect.right < screenWidth) {
		 deltaX = screenWidth - rect.right;
		 }
		 }
		 matrix.postTranslate(deltaX, deltaY);
		 }

	
	public int getRotationAngle(){
		int angle = (rotateAngle % 360);
		if(angle < 0){
			angle += 360;
		}
		
		Log.d(Constants.TAG,"angle = " + angle);
		return angle;
	}
	
	public void setFilePath(String path){
		mFilePath = path;
	}
	
	public Rect getScaleRectInOrignalBitmap(){
		Rect ret = new Rect();
		
		//get the image's orignal size
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(mFilePath, options);
		
		Log.d(Constants.TAG,"orignal = width=" + options.outWidth +  " ,height=" +options.outHeight);
		//Rect srcRect = new Rect(mLeft+30,mTop+26,mLeft+330,mTop+226);
		Rect srcRect = new Rect(mLeft+mMarginLeft,mTop+mMarginTop,mLeft+mMarginLeft+mClipWidth,mTop+mMarginTop+mClipHeight);
		int angle = getRotationAngle();
		int orignalWidth = options.outWidth;
		int orignalHeight = options.outHeight;
		if(angle %180!=0){
			orignalWidth = options.outHeight;
			orignalHeight = options.outWidth;
		}
		
		int top = (int) (((double)orignalHeight * srcRect.top) / mSrcBitmap.getHeight());
		int left = (int) (((double)orignalWidth * srcRect.left) / mSrcBitmap.getWidth());
		int width = (int) (((double)orignalWidth * mClipWidth) / mSrcBitmap.getWidth());
		int height = (int)(((double)orignalHeight * mClipHeight)/mSrcBitmap.getHeight());
		
		ret.set(left,top,left+width,top+height);
		Log.d(Constants.TAG,"rect = " + ret);
		
		
		return ret;
	}
	
	private void ensureCenter(){
		mLeft = (mSrcBitmapWidth - mDefaultWidth)/2;
		mTop = (mSrcBitmapHeight - mDefaultHeight)/2;
		
		Log.d(TAG, "mTop=" + mTop + ",mLeft=" + mLeft);
		center(true,true);
	}
	
	public void reset(){
		mScale = 1.0F;
		rotateAngle=0;
		mFilePath = null;
	}
	
	public void release()
	{
		if(mSrcBitmap!= null && !mSrcBitmap.isRecycled())
			mSrcBitmap.recycle();
		mSrcBitmap = null;
		
		if(mOrignalBitmap!= null && !mOrignalBitmap.isRecycled())
			mOrignalBitmap.recycle();
		mOrignalBitmap = null;

	}
	
	/*******************************zoom*****************/
	
	private boolean matrixCheck() { 
        float[] f = new float[9]; 
        matrix1.getValues(f); 
 
        float x1 = f[0] * 0 + f[1] * 0 + f[2]; 
        float y1 = f[3] * 0 + f[4] * 0 + f[5]; 
        float x2 = f[0] * mSrcBitmap.getWidth() + f[1] * 0 + f[2]; 
        float y2 = f[3] * mSrcBitmap.getWidth() + f[4] * 0 + f[5]; 
        float x3 = f[0] * 0 + f[1] * mSrcBitmap.getHeight() + f[2]; 
        float y3 = f[3] * 0 + f[4] * mSrcBitmap.getHeight() + f[5]; 
        float x4 = f[0] * mSrcBitmap.getWidth() + f[1] * mSrcBitmap.getHeight() + f[2]; 
        float y4 = f[3] * mSrcBitmap.getWidth() + f[4] * mSrcBitmap.getHeight() + f[5]; 

        double width = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 
  
        if (width < mDefaultWidth / 3 || width > mDefaultWidth * 3) { 
            return true; 
        } 
        // 出界判断 
        if ((x1 < mDefaultWidth / 3 && x2 < mDefaultWidth / 3 
                && x3 < mDefaultWidth / 3 && x4 < mDefaultWidth / 3) 
                || (x1 > mDefaultWidth * 2 / 3 && x2 > mDefaultWidth * 2 / 3 
                        && x3 > mDefaultWidth * 2 / 3 && x4 > mDefaultWidth * 2 / 3) 
                || (y1 < mDefaultHeight / 3 && y2 < mDefaultHeight / 3 
                        && y3 < mDefaultHeight / 3 && y4 < mDefaultHeight / 3) 
                || (y1 > mDefaultHeight * 2 / 3 && y2 > mDefaultHeight * 2 / 3 
                        && y3 > mDefaultHeight * 2 / 3 && y4 > mDefaultHeight * 2 / 3)) { 
            return true; 
        } 
        return false; 
    }
	

    private float spacing(MotionEvent event) { 
        float x = event.getX(0) - event.getX(1); 
        float y = event.getY(0) - event.getY(1); 
        return FloatMath.sqrt(x * x + y * y); 
    } 

    private void midPoint(PointF point, MotionEvent event) { 
        float x = event.getX(0) + event.getX(1); 
        float y = event.getY(0) + event.getY(1); 
        point.set(x / 2, y / 2); 
    } 
 

    private float rotation(MotionEvent event) { 
        double delta_x = (event.getX(0) - event.getX(1)); 
        double delta_y = (event.getY(0) - event.getY(1)); 
        double radians = Math.atan2(delta_y, delta_x); 
        return (float) Math.toDegrees(radians); 
    } 
 

}
